package com.syh.jn.scm.domain.supplier.entity.base.downstream;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.util.other.ExtAssert;
import cn.redscarf.commons.spring.SpringContextUtils;
import cn.redscarf.commons.util.validator.ValidationUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.domain.CodeExpEnum;
import com.syh.core.ddd.domain.CodeGenerateUtil;
import com.syh.jn.scm.domain.downstream.repository.base.DownGoodsExtCodeReadRepository;
import com.syh.jn.scm.domain.supplier.repository.base.downstream.DownstreamPriceTemplateReadRepository;
import com.syh.jn.scm.domain.supplier.repository.finance.*;
import com.syh.jn.scm.domain.supplier.repository.sale.SaleOrderReadRepository;
import com.syh.jn.scm.domain.supplier.repository.sale.SaleReturnOrderReadRepository;
import com.syh.jn.scm.domain.support.SuperBusinessAggregate;
import com.syh.jn.scm.dto.supplier.base.downstream.DownstreamAddressSto;
import com.syh.jn.scm.dto.supplier.base.downstream.DownstreamMto;
import com.syh.jn.scm.dto.supplier.base.downstream.DownstreamSto;
import com.syh.jn.scm.exception.BusinessException;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * 下游客户
 */
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class Downstream extends SuperBusinessAggregate<Long> {

    /**
     * 新建下游客户
     *
     * @param sto
     * @return
     */
    public static Downstream create(DownstreamSto sto) {
        ExtAssert.notNull(sto, "对象为空");
        ValidationUtils.validate(sto);
        Downstream downstream = new Downstream();
        downstream.status = Short.valueOf("1");
        downstream.createTimeStamp = System.currentTimeMillis();
        downstream.setUuid(UUID.randomUUID().toString());
        downstream.setBusinessEntityId(sto.getBusinessEntityId());
        downstream.setCode(CodeGenerateUtil.merchantCodeGenerate(CodeExpEnum.DOWNSTREAM_CODE_EXP.getCodeExp()));
        downstream.setAddressesItem(new ArrayList<>());
        ExtBeanUtils.copyProperties(sto, downstream);

        if (downstream.beginPaymentTotalAmount == null) {
            downstream.beginPaymentTotalAmount = BigDecimal.ZERO;
        }


        sto.getAddressListSto().stream().forEach((addressSto) -> {
            downstream.addAddress(DownstreamAddress.create(addressSto));
        });
        return downstream;
    }

    /**
     * 修改下游客户
     *
     * @param mto
     */
    public void modify(DownstreamMto mto) {
        ExtAssert.notNull(mto, "对象为空");
        ValidationUtils.validate(mto);
        ExtBeanUtils.copyProperties(mto, this);
        //code不符合规则则重新生成code
        if (!CodeGenerateUtil.checkExp(CodeExpEnum.DOWNSTREAM_CODE_EXP.getCodeRegexp(), this.code))
            this.code = CodeGenerateUtil.merchantCodeGenerate(CodeExpEnum.DOWNSTREAM_CODE_EXP.getCodeExp());
        this.addressesItem = new ArrayList<>();
        mto.getAddressListMto().stream().forEach((addressMto) -> {
            DownstreamAddressSto sto = ExtBeanUtils.copyProperties(addressMto, new DownstreamAddressSto(), true);
            DownstreamAddress downstreamAddress = DownstreamAddress.create(sto);
            this.addAddress(downstreamAddress);
        });
        this.lastUpdateTimeStamp = System.currentTimeMillis();
    }

    /**
     * 启用下游客户
     */
    public void enabled() {
        this.status = 1;
    }

    /**
     * 停用下游客户
     */
    public void disabled() {
        this.status = -1;
    }

    /**
     * 绑定价格模板id
     *
     * @param priceTemplateId
     */
    public void bindingPriceTemplate(Long priceTemplateId) {
        ExtAssert.notNull(priceTemplateId, "价格模板id为空");
        DownstreamPriceTemplateReadRepository dsPriceTemplateRead = (DownstreamPriceTemplateReadRepository) SpringContextUtils.getBean(DownstreamPriceTemplateReadRepository.class);
        DownstreamPriceTemplate dsPriceTemplate = dsPriceTemplateRead.getById(priceTemplateId);
        if (!dsPriceTemplate.getStatus().equals(Short.valueOf("1")))
            throw new BusinessException("该报价模板未启用，绑定失败！");

        this.priceTemplateId = priceTemplateId;
    }

    /**
     * 解除价格模板
     */
    public void removePriceTemplate() {
        this.priceTemplateId = null;
    }

    /**
     * 增加地址项
     *
     * @param item
     * @return
     */
    public Downstream addAddress(DownstreamAddress item) {
        this.addressesItem.add(item);
        return this;
    }

    /**
     * 数据销毁
     */
    public void destroy() {
        //查看销售单是否有数据存在
        SaleOrderReadRepository saleOrder = (SaleOrderReadRepository) SpringContextUtils.getBean("saleOrderRepositoryImpl");
        Wrapper saleWrapper = Wrapper.build();
        saleWrapper.append(Restrictions.eq("downStreamCompanyId", this.id));
        Integer saleCount = saleOrder.getCount(saleWrapper);
        if (saleCount > 0) {
            throw new BusinessException("销售单存在该数据,删除失败");
        }
        //查看销售退货是否有数据存在
        SaleReturnOrderReadRepository saleReturn = (SaleReturnOrderReadRepository) SpringContextUtils.getBean(SaleReturnOrderReadRepository.class);
        Wrapper saleReturnWrapper = Wrapper.build();
        saleReturnWrapper.append(Restrictions.eq("downStreamCompanyId", this.id));
        Integer saleReturnCount = saleReturn.getCount(saleReturnWrapper);
        if (saleReturnCount > 0) {
            throw new BusinessException("销售退货单存在该数据,删除失败");
        }
        //查看对账单是否有数据存在
        StatementAccountBillReadRepository statementBill = (StatementAccountBillReadRepository) SpringContextUtils.getBean(StatementAccountBillReadRepository.class);
        Wrapper statementBillWrapper = Wrapper.build();
        statementBillWrapper.append(Restrictions.eq("customerId", this.id));
        statementBillWrapper.append(Restrictions.eq("customerType", Short.valueOf("1")));
        Integer statementCount = statementBill.getCount(statementBillWrapper);
        if (statementCount > 0) {
            throw new BusinessException("对账单存在该数据,删除失败");
        }
        //查看费用单是否有数据存在
        CostBillReadRepository costBill = (CostBillReadRepository) SpringContextUtils.getBean(CostBillReadRepository.class);
        Wrapper costBillWrapper = Wrapper.build();
        costBillWrapper.append(Restrictions.eq("customerId", this.id));
        costBillWrapper.append(Restrictions.eq("customerType", Short.valueOf("1")));
        Integer costCount = costBill.getCount(costBillWrapper);
        if (costCount > 0) {
            throw new BusinessException("费用单存在该数据,删除失败");
        }
        //查看收入单是否有数据存在
        IncomeBillReadRepository incomeBill = (IncomeBillReadRepository) SpringContextUtils.getBean(IncomeBillReadRepository.class);
        Wrapper incomeBillWrapper = Wrapper.build();
        incomeBillWrapper.append(Restrictions.eq("customerId", this.id));
        incomeBillWrapper.append(Restrictions.eq("customerType", Short.valueOf("1")));
        Integer incomeCount = incomeBill.getCount(incomeBillWrapper);
        if (incomeCount > 0) {
            throw new BusinessException("收入单存在该数据,删除失败");
        }
        //查看收款单是否有数据存在
        ReceiptBillReadRepository receiptBill = (ReceiptBillReadRepository) SpringContextUtils.getBean(ReceiptBillReadRepository.class);
        Wrapper receiptBillWrapper = Wrapper.build();
        receiptBillWrapper.append(Restrictions.eq("customerId", this.id));
        receiptBillWrapper.append(Restrictions.eq("customerType", Short.valueOf("1")));
        Integer receiptCount = receiptBill.getCount(receiptBillWrapper);
        if (receiptCount > 0) {
            throw new BusinessException("收款单存在该数据,删除失败");
        }
        //查看付款单是否有数据存在
        PaymentBillReadRepository paymentBill = (PaymentBillReadRepository) SpringContextUtils.getBean(PaymentBillReadRepository.class);
        Wrapper paymentBillWrapper = Wrapper.build();
        paymentBillWrapper.append(Restrictions.eq("customerId", this.id));
        paymentBillWrapper.append(Restrictions.eq("customerType", Short.valueOf("1")));
        Integer paymentCount = paymentBill.getCount(paymentBillWrapper);
        if (paymentCount > 0) {
            throw new BusinessException("付款单存在该数据,删除失败");
        }
        //扩展编码是否有数据
        DownGoodsExtCodeReadRepository goodsExtCodeReadRepository = (DownGoodsExtCodeReadRepository) SpringContextUtils.getBean(DownGoodsExtCodeReadRepository.class);
        Wrapper goodsExtCodeWrapper = Wrapper.build();
        goodsExtCodeWrapper.append(Restrictions.eq("businessEntityId", this.id));
        Integer goodsExtCount = goodsExtCodeReadRepository.getCount(goodsExtCodeWrapper);
        if (goodsExtCount > 0) {
            throw new BusinessException("该下游存在对商品填写了扩展编码,删除失败");
        }
    }


    /**
     * 分类id
     */
    private Long categoryId;
    /**
     * 所属种类,应用分类编码
     */
    private String categoryCode;
    /**
     * 归属id
     */
    private Long businessEntityId;
    /**
     * 地址省 市 区
     */
    private String area;
    /**
     * 单位注册地址
     */
    private String address;
    /**
     * 地区编号
     */
    private String areaCode;
    /**
     * 单位编号
     */
    private String code;
    /**
     * 单位名称
     */
    private String name;
    /**
     * 法人代表
     */
    private String legalRepresentative;
    /**
     * 注册资金（单位 ：万元）
     */
    private Integer registeredCapital;
    /**
     * 识别号
     */
    private String registrationCode;
    /**
     * 状态: -1停用, 1可用
     */
    private Short status;
    /**
     * 对公电子邮件
     */
    private String email;
    /**
     * 公司联系电话
     */
    private String tel;
    /**
     * 销售代表id
     */
    private Long salesmanId;
    /**
     * 客户报价模板Id
     */
    private Long priceTemplateId;
    /**
     * 营业执照图片url,保存格式json字符串{"img":"www.test.com","img":"www.demo.com"}
     */
    private String businessLicense;
    /**
     * 期初应收总额
     */
    private BigDecimal beginReceiveTotalAmount;
    /**
     * 期初应付总额
     */
    private BigDecimal beginPaymentTotalAmount;
    /**
     * 地址项
     */
    private List<DownstreamAddress> addressesItem;


}
